package org.hongqi.common.senpec.sys.user;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hongqi.common.senpec.base.mybatisplus.IBaseServiceImpl;
import org.hongqi.common.senpec.base.sevlet.Result;
import org.hongqi.common.senpec.base.utils.ObjectsUtil;
import org.hongqi.common.senpec.file.easyExcel.EasyExcelService;
import org.hongqi.common.senpec.file.fileInfo.FileInfo;
import org.hongqi.common.senpec.file.fileInfo.FileInfoService;
import org.hongqi.common.senpec.sys.department.DepartmentService;
import org.hongqi.common.senpec.sys.user.export.UserExport;
import org.hongqi.common.senpec.sys.user.export.UserExportListener;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl extends IBaseServiceImpl<UserMapper, User> implements UserService {
    private final UserMapper userMapper;
    private final DepartmentService departmentService;
    private final PasswordEncoder passwordEncoder;
    private final EasyExcelService<UserExport> easyExcelService;
    private final UserExportListener userExportListener;
    private final FileInfoService fileInfoService;

    @Override
//    @PreAuthorize("hasAuthority('user:save')")
    public Result<User> mySave(User user) {
        Collection<User> usersSelected = userMapper.selectAllByUsernameOrJobnoOrEmailOrPhoneOrIdCard(user);
        if (usersSelected.isEmpty()) {
            user.setHeadImageUuid(UUID.randomUUID().toString());
            if (user.getPassword() == null) {
                user.setPassword(passwordEncoder.encode("admin12345678"));
            }

            if (ObjectsUtil.isNull(user.getDepartment())) {
                user.setDepartment(0L);
            }

            try {
                userMapper.insert(user);
                return Result.ok(user);
            } catch (Exception e) {
                return Result.error(user).msg(e.getMessage());
            }
        } else {
            String msg = "没有重复的内容。";
            if (usersSelected.stream().anyMatch(userSelected -> userSelected.getUsername().equals(user.getUsername()))) {
                msg = "帐号已存在，请修改后重新提交。";
            } else if (usersSelected.stream().anyMatch(userSelected -> userSelected.getJobno().equals(user.getJobno()))) {
                msg = "工号已存在，请修改后重新提交。";
            } else if (usersSelected.stream().anyMatch(userSelected -> userSelected.getEmail().equals(user.getEmail()))) {
                msg = "邮箱已存在，请修改后重新提交。";
            } else if (usersSelected.stream().anyMatch(userSelected -> userSelected.getIdCard().equals(user.getIdCard()))) {
                msg = "身份证已存在，请修改后重新提交。";
            } else if (usersSelected.stream().anyMatch(userSelected -> userSelected.getPhone().equals(user.getPhone()))) {
                msg = "手机已存在，请修改后重新提交。";
            }
            return Result.error(user).msg(msg);
        }

    }

    @Override
//    @PreAuthorize("hasAuthority('user:remove')")
    public Result<?> myRemoveById(Long id) {
        int deletedNum = userMapper.deleteById(id);
        return deletedNum > 0 ? Result.ok().msg("删除成功") : Result.error().msg("删除失败");
    }

    @Override
//    @PreAuthorize("hasAuthority('user:update')")
    public Result<User> myUpdateById(User user) {
        log.info("updateUser is running with {}", user);
        Collection<User> usersSelected = userMapper.selectAllByUsernameOrJobnoOrEmailOrPhoneOrIdCard(user).stream().filter(userSelected -> !Objects.equals(userSelected.getId(), user.getId())).toList();
        usersSelected.forEach(System.out::println);
        if (usersSelected.isEmpty()) {
            try {
                userMapper.updateById(user);
            } catch (Exception e) {
                return Result.error(user).msg(e.getMessage());
            }
        } else {
            String msg = "没有重复的内容";
            if (usersSelected.stream().anyMatch(userSelected -> ObjectsUtil.noNullAndEmpty(user.getUsername()) && !Objects.equals(userSelected.getId(), user.getId()) && userSelected.getUsername().equals(user.getUsername()))) {
                msg = "帐号已存在，请修改后重新提交。";
            } else if (usersSelected.stream().anyMatch(userSelected -> ObjectsUtil.noNullAndEmpty(user.getJobno()) && !Objects.equals(userSelected.getId(), user.getId()) && userSelected.getJobno().equals(user.getJobno()))) {
                msg = "工号已存在，请修改后重新提交。";
            } else if (usersSelected.stream().anyMatch(userSelected -> ObjectsUtil.noNullAndEmpty(user.getEmail()) && !Objects.equals(userSelected.getId(), user.getId()) && userSelected.getEmail().equals(user.getEmail()))) {
                msg = "邮箱已存在，请修改后重新提交。";
            } else if (usersSelected.stream().anyMatch(userSelected -> ObjectsUtil.noNullAndEmpty(user.getPhone()) && !Objects.equals(userSelected.getId(), user.getId()) && userSelected.getPhone().equals(user.getPhone()))) {
                msg = "电话已存在，请修改后重新提交。";
            } else if (usersSelected.stream().anyMatch(userSelected -> ObjectsUtil.noNullAndEmpty(user.getIdCard()) && !Objects.equals(userSelected.getId(), user.getId()) && userSelected.getIdCard().equals(user.getIdCard()))) {
                msg = "身份证已存在，请修改后重新提交。";
            }
            return Result.error(user).msg(msg);
        }
        return Result.ok(user);
    }

    @Override
    public Result<User> myGetById(Long id) {
        User user = userMapper.selectById(id);
        FileInfo fileInfo = fileInfoService.getFileInfoByKeyword(user.getHeadImageUuid());
        if (ObjectsUtil.noNull(fileInfo)) {
            user.setHeadImageUrl(fileInfo.getUrl());
        }
        return Result.ok(user);
    }

    @Override
    public Result<IPage<User>> myListObjsWithPage(User user) {
        IPage<User> page = new Page<>(user.getCurrent(), user.getSize());
        IPage<User> iPage = userMapper.selectPage(page, createLambdaQueryWrapper(user));
        List<User> users = iPage.getRecords();
        users.forEach(item -> {
            item.setCreatorObj(userMapper.selectById(item.getCreator()));
            item.setUpdaterObj(userMapper.selectById(item.getUpdater()));
            item.setDepartmentObj(departmentService.getById(item.getDepartment()));
            FileInfo fileInfo = fileInfoService.selectByKeyword(item.getHeadImageUuid());
            if (ObjectsUtil.noNull(fileInfo)) {
                item.setHeadImageUrl(fileInfo.getUrl());
            }
        });
        iPage.setRecords(users);
        return Result.ok(iPage);
    }

    @Override
    public Result<Collection<User>> myListObjsWithoutPage(User user) {
        List<User> users = userMapper.selectList(null);
        users.forEach(item -> {
            item.setCreatorObj(userMapper.selectById(item.getCreator()));
            item.setUpdaterObj(userMapper.selectById(item.getUpdater()));
            item.setDepartmentObj(departmentService.getById(item.getDepartment()));
        });

        return Result.ok(users);
    }

    @Override
    public void myExportObjs(HttpServletResponse response) {
        List<User> users = userMapper.selectList(null);
        List<UserExport> userExports = new ArrayList<>();
        for (User user : users) {
            UserExport userExport = new UserExport();
            BeanUtils.copyProperties(user, userExport);
            userExports.add(userExport);
        }
        easyExcelService.exportData(response, UserExport.class, userExports, "用户清单");
    }

    @Override
    public void myImportObjs(Long creator, MultipartFile file) {
        try {
            easyExcelService.importData(file, UserExport.class, userExportListener);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public User myGetByUsername(String username) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getUsername, username);
        return userMapper.selectOne(lambdaQueryWrapper);
    }

    @Override
    public Collection<String> myListAuthoritiesByUsername(String username) {
        return UserService.super.myListAuthoritiesByUsername(username);
    }

    @Override
    public LambdaQueryWrapper<User> createLambdaQueryWrapper(User user) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper//
                .like(StringUtils.isNotBlank(user.getName()), User::getName, user.getName())//
                .like(StringUtils.isNotBlank(user.getUsername()), User::getUsername, user.getUsername())//
                .like(StringUtils.isNotBlank(user.getIdCard()), User::getIdCard, user.getIdCard())//
                .like(StringUtils.isNotBlank(user.getPhone()), User::getPhone, user.getPhone())//
                .like(StringUtils.isNotBlank(user.getJobno()), User::getJobno, user.getJobno())//
                .eq(ObjectsUtil.noNullAndEmpty(user.getGender()), User::getGender, user.getGender())//
                .in(user.getIncludeAfter() && user.getDepartment() > 0, User::getDepartment, departmentService.myListChildrenIdsByPid(user.getDepartment()))//
                .eq(!user.getIncludeAfter() && user.getDepartment() > 0, User::getDepartment, user.getDepartment())//
                .orderByDesc(User::getId);
        return lambdaQueryWrapper;
    }


}
